/**
* 创建者：luyiming
* 该组件用于：
* 创建时间： 2019-12-27 23:13:24
* @param 参数说明
* @emit 事件使用说明
*/
import { cloneDeep } from 'lodash';

export default {
	name: 'VueEleForm_cmp',
	components: {
		AfterContent: {
			props: {
				content: {
					required: true
				}
			},
			render(h) {
				const _this = this;
				return (
					_this.content.after.content
						? _this.content.after.content(h, _this.content) :
						<span></span>
				);
			}
		}
	},
	props: {
		// 传入的需要渲染的表单
		formList: {
			type: Array,
			default: () => []
		},
		// 样式
		formStyle: {
			type: Object,
			default: () => ({
				width: '33%', // 必须是 % | px 结尾的单位
				labelWidth: '80px', // formitem的label的宽度
				labelPosition: 'right' // 表单每一个form对齐的样式 right | top | left
			})
		},
		title: {
			type: String,
			default: () => ''
		},
		// 是否在外面提交，控制提交按钮的显示
		outofSubmit: {
			type: Boolean,
			default: () => false
		},
		// 是否全部禁用
		isDisabled: {
			type: Boolean,
			default: () => false
		}
	},
	// 数据
	data() {
		return {
			// 渲染form的数据
			form: {
			},
			rules: {

			},
			formateData: [[]],
			mapIndex: {

			},
			fetchMapTimes:{

			},
			copyFormData: {

			},
		}

	},
	// 监听
	watch: {
		// form(){
		//     debugger
		// }
		formList() {
			this.typesetting()
		}
	},
	// Vue实例初始化完成
	created() {
		this.typesetting()
	},
	// Vue挂载完成
	mounted() {
		// window.addEventListener('resize', () => {
		// 	this.formList = this.formList.map(item => {
		// 		this.form.test = '111'
		// 		item.width = '20%'
		// 		return item
		// 	})
		// })
	},
	// Vue实例销毁前
	beforeDestroy() {

	},
	// 挂载的方法
	methods: {
        /**
        * 方法描述
        */
		exampleFunc() {
			return void 0
		},
		// 表单提交
		onSubmit(formName) {
			// this.$refs[formName].validate((valid) => {
			//     if (valid) {
			//         alert('submit!');
			//     } else {
			//         console.log('error submit!!');
			//         return false;
			//     }
			// });
			this.$emit("submit", this.form);
		},
		$$submit() {
			return this.form;
		},
		// 表单清空
		resetForm(formName) {
			this.$refs[formName].resetFields();
		},
		// 表单校验
		validate(callback) {
			this.$refs.form.validate(
				callback
			);
		},
        /**
         * 获取每一个form表单的样式
         * @param { item } Object
         */
		getColStyle(item) {
			const stylObj = {}
			stylObj.width = item.width * 100 + '%';
			if(item.style) {
				Object.assign(stylObj,item.style)
			}
			return stylObj
		},
        /**
         * 排版函数，根据宽度动态计算行列分布；
         */
		typesetting() {
			const formArray = cloneDeep(this.formList);
			const formContent = cloneDeep(this.form)
			const _self = this;
			// const newForm = {};
			// const newRules = {};
			const result = [[]];
			let is_1 = 0;
			let indexList = 0;
			while (formArray[0]) {
				const item = formArray.shift();
				const ownw = item.width || _self.formStyle.width;
				const praseNum = _self.praseWidth(ownw);
				if(_self.fetchMapTimes[item.moduleKey] === undefined){
					_self.fetchMapTimes[item.moduleKey] = item.fetchTimes || 1;
				}
				item.idKey = 'value'
				item.labelKey = 'label'

				if(item.optionsType){
					item.idKey = item.optionsType.id || item.idKey
					item.labelKey = item.optionsType.label || item.labelKey
				}
				delete item.optionsType
				if(item.fetch && typeof item.fetch === 'function'){
					if(!item.disFetch){
						if(_self.fetchMapTimes[item.moduleKey] > 0){
							_self.fetchMapTimes[item.moduleKey] --;
							item.fetch = item.fetch(item.query).then(res => {
								// debugger
								if(res instanceof Array){
									item.options = res
									item.disFetch = true
									// _self.formList[indexList].disFetch = true
								}else{
									item.options = []
								}
								return item.options;
							}).catch(
								err => {
									item.options = []
								}
							)
						}else{
							const indexs = _self.mapIndex[item.moduleKey] || [];
							if( indexs.length === 0 ) {
								item.options = []
							}else{
								const node = _self.formateData[indexs[0]][indexs[1]]
								item.fetch = node?.fetch
								node?.fetch?.then(res => {
									item.options = res;
								}).catch(err => {
									item.options = []
								}) || (item.options = [])
							}
						}

					}

				}
				// 设置form的默认值 如果当前的key已经存在，则不重置vue监听
				// if(_self.form[item.moduleKey] === undefined ){
					// 如果item.moduleKey存在，才添加监听
					if(!!item.moduleKey){
						_self.$set(_self.form, item.moduleKey, item.defaultValue || '')
						_self.$set(_self.rules, item.moduleKey, item.validate && item.validate() || [])
					}
				// }

				// newForm[item.moduleKey] = item.defaultValue || '';
				// newRules[item.moduleKey] = item.validate && item.validate() || [];
				// 设置每一项的宽度
				item.width = praseNum;
				// 计算是否在一行
				is_1 += praseNum
				if (is_1 < 1) {
					result[result.length - 1].push(item)
					_self.mapIndex[item.moduleKey] = [result.length - 1, result[result.length - 1].length -1 ]
					continue
				}
				is_1 = 0;
				indexList++;
				result.push([item])
				_self.mapIndex[item.moduleKey] = [result.length - 1, result[result.length - 1].length -1 ];
			}
			this.formateData = result
			Object.assign(_self.form, formContent)
			// _self.$set(_self, 'form', newForm)
			// _self.$set(_self, 'rules', newRules)
			// this.formateData = result;
		},
		getFormList(moduleKey){
			const indexs = this.mapIndex[moduleKey]
			const node = this.formateData[indexs[0]][indexs[1]]
			if(node && node.fetch){
				return node.fetch
			}
			return new Promise((res, rej) => {
				res(node.options || [])
			})
		},
		setDefaultValue(OBJ){
			// Object.assign(this.form, OBJ)
			Object.keys(OBJ).forEach(itemKey => {
				this.$set(this.form, itemKey, OBJ[itemKey])
			})
		},
		clearForm(){
			this.$refs.form.resetFields()
			delete this.form.id
		},
		clearValedate(){
			this.$refs.form.clearValidate()
		},
        /**
         * 编译传入的宽度
         * @param { widt } String
         */
		praseWidth(widt = '') {
			if (typeof widt !== 'string') {
				throw new Error('宽度必须是字符串')
			}
			let num = null;
			if (/(px)$/.test(widt)) {
				const ownnum = widt.replace('px', '') - 0;
				const wrapwidth = this.$refs.form.$el.clientWidth;
				num = Math.floor(ownnum / wrapwidth * 100000) / 100000;
			}
			if (/%$/.test(widt)) {
				num = (widt.replace('%', '') - 0) / 100;
			}
			if (typeof num !== 'number' || isNaN(num)) {
				throw new Error('输入字符串不合法，必须是px/%')
			}
			return num
		},
		/**
		 * 计算每一项表单的宽度占比
		 * 表单的宽度默认是 100%
		 * 宽度 = 100% - after的宽度 - ??
		 * @param { Object } item
		 */
		getItemInputWidth(item) {
			if (!item.after) {
				return '100%'
			}
			const subtract = item.after?.width || 0
			return `calc(100% - ${subtract})`
		},
		/**
		 * 删除Form/Rules中多余的key
		 * @warning 注意，当删除form中某一项时一定要调用此方法，避免造成多余的key污染
		 * @param { Array } keyW
		 */
		deleteKeys(keyW = []){
			const keys = cloneDeep(keyW)
			const _self = this;
			while (keys[0]){
				delete _self.form[keys[0]]
				delete _self.rules[keys[0]]
				keys.shift()
			}
		},
		/**
		 * 表单Form值发生改变时触发的函数
		 * @param { String } itemKey 触发change事件的key
		 * @return { itemKey } 将触发change事件的key返回到父组件，作为第一个参数
		 * @return { value } 触发change事件对应的value值
		 */
		changeForm(itemKey){
			this.$emit('change', itemKey, this.form[itemKey])
		},
		getFormData(){
			return this.form
		},
	},
}
